/*
 * File Name:               UIDragButton.cs
 * 
 * Description:             可以拖拽的按钮
 * Author:                  lisiyu <576603306@qq.com>

 * Create Date:             2017/05/19
 */

namespace UnityEngine.UI
{
    using UnityEngine;
    using EventSystems;
    using System;

    [AddComponentMenu("UI/DragButton - 2个事件")]
    [DisallowMultipleComponent]
    [RequireComponent(typeof(Image))]
    public class UIDragButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
    {
        public Action onClick;
        public Action onDragClick;

        public Sprite SpriteNormal;
        public Sprite SpriteDrag;

        public float MaxDistance = 15f;             // 移动节点与固定节点的最大距离
        private Vector3 mPointerDownPos;            // 按下时的位置

        private Vector3 mInitPos;
        private Image mImage;
        void Awake()
        {
            mInitPos = transform.localPosition;
            mImage = GetComponent<Image>();
        }

        public void OnDrag(PointerEventData eventData)
        {
            setMovedPos_ByScreen(eventData.position);
        }

        public void OnPointerDown(PointerEventData eventData)
        {
            mPointerDownPos = UIManager.Singleton.ScreenToWorldPoint(eventData.position, transform.position.z);
            setMovedPos_ByScreen(eventData.position);
        }

        public void OnPointerUp(PointerEventData eventData)
        {
            mImage.sprite = SpriteNormal;
            transform.localPosition = mInitPos;

            if(inNearArea)
            {
                if(onClick != null)
                    onClick();
            }
            else
            {
                if(onDragClick != null)
                    onDragClick();
            }
        }

        private bool inNearArea;
        private void setMovedPos_ByScreen(Vector2 screenPos)
        {
            var retPos = UIManager.Singleton.ScreenToWorldPoint(screenPos, transform.position.z);

            var dir = (retPos - mPointerDownPos);
            if (dir.magnitude > MaxDistance)
            {
                dir = (retPos - mPointerDownPos).normalized * MaxDistance;
            }
            
            if(dir.magnitude > MaxDistance / 2)
            {
                inNearArea = false;
                mImage.sprite = SpriteDrag;
            }
            else
            {
                inNearArea = true;
                mImage.sprite = SpriteNormal;
            }
            
            retPos = mPointerDownPos + dir;
            transform.position = retPos;
        }

        private void OnDisable()
        {
            mImage.sprite = SpriteNormal;
            transform.localPosition = mInitPos;
        }
    }
}